package com.coder.rental.security;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import java.security.SecureRandom;

/**
 * 密码处理器
 * spring security提供
 * 在数据库中存入密文，这样若数据库数据泄露，也无法得知密码
 */
@Configuration
@Data
public class PasswordConfig {

    // 调用：
//    public BCryptPasswordEncoder(int strength, SecureRandom random) {
//        this(BCryptPasswordEncoder.BCryptVersion.$2A, strength, random);
//    }

    // 通过@Value注解从应用的配置文件中动态注入加密强度值。
    @Value("${encoder.ctype.strength}") // 在yml文件中先配置一下密码相关属性
    private int strength; // 强度

    // 通过@Value注解从应用的配置文件中动态注入加密使用的密钥。
    // BCryptPasswordEncoder 中，密码加密算法的设计目的是为了增加加密的安全性，而 secret 作为一种种子（或盐值）用于生成 SecureRandom 实例
    @Value("${encoder.ctype.secret}")
    private String secret;

    // 强散列加密处理方式
    // 保证相同明文进行多次加密之后，密文有相同的散列数据，但是每次结果不一样
    @Bean // 通常与 @Configuration 配合使用，因为 @Configuration 类会扫描 @Bean 注解并将返回的对象作为 Bean 管理。
    public BCryptPasswordEncoder passwordEncoder() {
        // 使用secret生成一个SecureRandom实例，以增加加密过程的随机性。
        // 此密码编码器使用指定的加密强度和基于secret参数生成的SecureRandom实例。
        SecureRandom secureRandom = new SecureRandom(secret.getBytes());
        return new BCryptPasswordEncoder(strength, secureRandom);
    }

//    public static void main(String[] args) {
//        BCryptPasswordEncoder passwordEncoder = new PasswordConfig().passwordEncoder();
//        String password1 = "{bcrypt}" + passwordEncoder.encode("admin"); // $2a$06$0c/ndr5FZ87vzmlIVJdUd.UyQKp296WpR60wwywVi1gYHrvSiyAZW
//        System.out.println(password1);
//        String password2 = "{bcrypt}" + passwordEncoder.encode("111111"); // $2a$06$s38Vw8g3D99w2e.4.MPl..eN4zcYxsJcrBVqsVxJ8VFLOFwCRXM5i
//        System.out.println(password2);
//        boolean a = passwordEncoder.matches("admin", password1);
//        boolean b = passwordEncoder.matches("111111", password2);
//        System.out.println(a + " " + b);
//    }
}
